package com.youhome.controller;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.youhome.model.Zip;
import com.youhome.response.*;
import com.youhome.service.DownloadService;
import com.youhome.service.ZipService;
import com.youhome.utils.DateUtils;
import com.youhome.utils.StateUtils;
import com.youhome.utils.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by chen365 on 2018/07/24.
 */
@RestController
@Api(tags = "分析")
@RequestMapping("/analysis")
public class AnalysisController {
    //是否查询相邻邮编数据
    @Value("${zillow.isSearchAdjacentZip}")
    private Boolean isSearchAdjacentZip;

    @Autowired
    private DownloadService downloadService;
    @Autowired
    private ZipService zipService;

    /**
     * 获取 json 中的 time 数据
     *
     * @param json 原始 json
     * @param year 年，0代表所有，其它代表年
     * @return
     */
    public static List<TimeValueItemResult> getSeriesDataByYear(String json, Integer year) {
        JSONObject jsonObject = JSONObject.parseObject(json);
        if (jsonObject.get("time") != null) {
            String time = jsonObject.get("time").toString();
            ObjectMapper mapper = new ObjectMapper();
            List<TimeValueItemResult> timeValueItemResult = null;
            try {
                timeValueItemResult = mapper.readValue(time, new TypeReference<List<TimeValueItemResult>>() {
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
            //0年 表示获取所有数据
            if (year != 0 && year > 0) {
                String dateFormat = "yyyy-MM";
                Date eTime = new Date();
                Date bTime = DateUtils.addYear(eTime, -year);
                //开始截取的时间
                String startTime = DateUtils.formatDate(bTime, dateFormat);
                Boolean flag = false; // 开始截取标识
                List<TimeValueItemResult> items = new ArrayList<>();
                for (TimeValueItemResult item : timeValueItemResult) {
                    Integer a = Integer.valueOf(item.getTime().replaceAll("-", ""));
                    Integer b = Integer.valueOf(startTime.replaceAll("-", ""));
                    if (a >= b) {
                        flag = true;
                    }
                    if (flag) {
                        System.err.println("item:" + item);
                        items.add(item);
                    }
                }
                return items;
            }
            return timeValueItemResult;
        }
        return null;
    }

    public static List<TimeValueItemResult> getTimeSeriesDataByYear(String json, Integer year) {
        ObjectMapper mapper = new ObjectMapper();
        List<TimeValueItemResult> timeValueItemResult = null;
        try {
            timeValueItemResult = mapper.readValue(json, new TypeReference<List<TimeValueItemResult>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        //0年 表示获取所有数据
        if (year != 0 && year > 0) {
            String dateFormat = "yyyy-MM-dd";
            Date eTime = new Date();
            Date bTime = DateUtils.addYear(eTime, -year);
            //开始截取的时间
            String startTime = DateUtils.formatDate(bTime, dateFormat);
            Boolean flag = false; // 开始截取标识
            List<TimeValueItemResult> items = new ArrayList<>();
            for (TimeValueItemResult item : timeValueItemResult) {
                String time = item.getTime();
                if(time.indexOf(" ") > -1) {
                    time = time.substring(0, time.indexOf(" "));
                }
                Integer a = Integer.valueOf(time.replaceAll("-", ""));
                Integer b = Integer.valueOf(startTime.replaceAll("-", ""));
                if (a >= b) {
                    flag = true;
                }
                if (flag) {
                    System.err.println("item:" + item);
                    items.add(item);
                }
            }
            return items;
        }
        return timeValueItemResult;

    }

    @ApiOperation(value = "时间序列", notes = "时间序列", response = TimeValueItemResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "int", name = "time", value = "年(默认0,0:表示所有,1：1年,2:2年)", required = false, paramType = "query")
    })
    @GetMapping(value = "/time/{type}/{zip}")
    public Object time(@PathVariable String type, @PathVariable String zip, @RequestParam(value = "time", defaultValue = "0") Integer t) {
        String key = "zillow/" + getType(type) + "/" + zip + ".json";
        // 90 : 卖房成功比例  按城市统计	月更新
        // 91 : 中位挂牌时间 以城市为准 	月更新
        // 95 : 房产销售数量 按city统计
        // 104:中位家庭收入   都会区  季度更新
        // 86:贷款能力 87:价格收入比 88:租金能力--季度更新
        boolean isZipSearch = true; //是否按邮编方式查询
        if (type.equals("90") || type.equals("91") || type.equals("95") || type.equals("104")) {
            Zip entity = zipService.selectByPrimaryKey(zip);
            if (entity == null)
                return new Result(ResultCode.NO_DATA_WAS_FOUND);
            String city = entity.getCity();
            String state = entity.getState();
            if (StringUtils.isEmpty(city)) {
                System.err.println("================>>city is null");
                return new Result(ResultCode.CITY_NULL);
            }
            if (StringUtils.isEmpty(state)) {
                System.err.println("================>>state is null");
                return new Result(ResultCode.STATE_NULL);
            }
            if (type.equals("95")) {
                state = StateUtils.convert(state); // 州缩写转全称
            }
            key = "zillow/" + getType(type) + "/" + StringUtil.replaceBlankAndComma(city) + "_" + StringUtil.replaceBlankAndComma(state) + ".json";
        }
        if (type.equals("86") || type.equals("87") || type.equals("88")) {
            Zip entity = zipService.selectByPrimaryKey(zip);
            if (entity == null)
                return new Result(ResultCode.NO_DATA_WAS_FOUND);
            String metro = entity.getMetro();
            if (StringUtils.isEmpty(metro)) {
                System.err.println("================>>metro is null");
                return new Result(ResultCode.METRO_NULL);
            }
            if (type.equals("86")) {
                key = "zillow/" + getType(type) + "/" + StringUtil.replaceBlankAndComma(metro) + "_mortgage_affordability.json";
            }
            if (type.equals("87")) {
                key = "zillow/" + getType(type) + "/" + StringUtil.replaceBlankAndComma(metro) + "_price_to_income.json";
            }
            if (type.equals("88")) {
                key = "zillow/" + getType(type) + "/" + StringUtil.replaceBlankAndComma(metro) + "_rent_affordability.json";
            }
        }

        System.err.println("===>>key:"+key);
        String json = downloadService.downloadJsonFromOSS(key);
        System.err.println(json);


        //重新获取相邻邮编数据
        if (StringUtils.isEmpty(json) && isZipSearch) {
            json = getNextToZipJsonByZips(getType(type), zip);
        }

        try {
            if (!StringUtils.isEmpty(json)) {
                JSONObject jsonObject = JSONObject.parseObject(json);
                if (jsonObject.get("time") != null) {
                    String time = jsonObject.get("time").toString();
                    ObjectMapper mapper = new ObjectMapper();
                    List<TimeValueItemResult> timeValueItemResult = mapper.readValue(time, new TypeReference<List<TimeValueItemResult>>() {
                    });

                    //0年 表示获取所有数据
                    if (t != 0 && t > 0) {
                        String dateFormat = "yyyy-MM";
                        Date eTime = new Date();
                        Date bTime = DateUtils.addYear(eTime, -t);
                        //开始截取的时间
                        String startTime = DateUtils.formatDate(bTime, dateFormat);
                        Boolean flag = false; // 开始截取标识
                        List<TimeValueItemResult> items = new ArrayList<>();
                        for (TimeValueItemResult item : timeValueItemResult) {
                            System.err.println(item.getTime() + "=====" + startTime);
                            if (item.getTime().compareTo(startTime) > -1) {
                                flag = true;
                            }
                            if (flag) {
                                System.err.println("item:" + item);
                                items.add(item);
                            }
                        }
                        return new Result<>(ResultCode.SUCCESS, items);
                    }

                    return new Result<>(ResultCode.SUCCESS, timeValueItemResult);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "房租", notes = "房租", response = ZriResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path")
    })
    @GetMapping(value = "/zri/{type}/{zip}")
    public Object zri(@PathVariable String type, @PathVariable String zip) {
        type = getType(type);
        String key = "zillow/" + type + "/" + zip + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);
        //重新获取相邻邮编数据
        if (StringUtils.isEmpty(json)) {
            json = getNextToZipJsonByZips(type, zip);
        }

        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            ZriResult zriResult = new ZriResult();
            if (!StringUtils.isEmpty(jsonObject.get("Zri"))) {
                zriResult.setZri(Double.valueOf(jsonObject.get("Zri").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("MoM"))) {
                zriResult.setMom(Double.valueOf(jsonObject.get("MoM").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("QoQ"))) {
                zriResult.setQoq(Double.valueOf(jsonObject.get("QoQ").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("YoY"))) {
                zriResult.setYoy(Double.valueOf(jsonObject.get("YoY").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("ZriRecordCnt"))) {
                zriResult.setZri_record_cnt(Double.valueOf(jsonObject.get("ZriRecordCnt").toString()));
            }
            return new Result<>(ResultCode.SUCCESS, zriResult);
        }

        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "房屋价格指数", notes = "房屋价格指数", response = ZhviResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path")
    })
    @GetMapping(value = "/zhvi/{type}/{zip}")
    public Object zhvi(@PathVariable String type, @PathVariable String zip) {
        type = getType(type);
        String key = "zillow/" + type + "/" + zip + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);
        //重新获取相邻邮编数据
        if (StringUtils.isEmpty(json)) {
            json = getNextToZipJsonByZips(type, zip);
        }
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            ZhviResult zhviResult = new ZhviResult();

            if (!StringUtils.isEmpty(jsonObject.get("Zhvi"))) {
                zhviResult.setZhvi(Double.valueOf(jsonObject.get("Zhvi").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("MoM"))) {
                zhviResult.setMom(Double.valueOf(jsonObject.get("MoM").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("QoQ"))) {
                zhviResult.setQoq(Double.valueOf(jsonObject.get("QoQ").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("YoY"))) {
                zhviResult.setYoy(Double.valueOf(jsonObject.get("YoY").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("5Year"))) {
                zhviResult.setY_5(Double.valueOf(jsonObject.get("5Year").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("10Year"))) {
                zhviResult.setY_10(Double.valueOf(jsonObject.get("10Year").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("PeakMonth"))) {
                zhviResult.setPeak_month(jsonObject.get("PeakMonth").toString());
            }
            if (!StringUtils.isEmpty(jsonObject.get("PeakQuarter"))) {
                zhviResult.setPeak_quarter(jsonObject.get("PeakQuarter").toString());
            }
            if (!StringUtils.isEmpty(jsonObject.get("PeakZHVI"))) {
                zhviResult.setPeak_zhvi(Double.valueOf(jsonObject.get("PeakZHVI").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("PctFallFromPeak"))) {
                zhviResult.setPct_fall_from_peak(Double.valueOf(jsonObject.get("PctFallFromPeak").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("LastTimeAtCurrZHVI"))) {
                zhviResult.setLast_time_at_curr_zhvi(jsonObject.get("LastTimeAtCurrZHVI").toString());
            }

            return new Result<>(ResultCode.SUCCESS, zhviResult);
        }

        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "买卖指数", notes = "买卖指数", response = BuyerSellerResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path")
    })
    @GetMapping(value = "/buyerSeller/{type}/{zip}")
    public Object buyerSeller(@PathVariable String type, @PathVariable String zip) {
        type = getType(type);
        String key = "zillow/" + type + "/" + zip + ".json";
        String json = downloadService.downloadJsonFromOSS(key);
        //重新获取相邻邮编数据
        if (StringUtils.isEmpty(json)) {
            json = getNextToZipJsonByZips(type, zip);
        }
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            BuyerSellerResult buyerSellerResult = new BuyerSellerResult();

            if (!StringUtils.isEmpty(jsonObject.get("PctPriceCut"))) {
                buyerSellerResult.setPct_price_cut(Double.valueOf(jsonObject.get("PctPriceCut").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("DaysOnMarket"))) {
                buyerSellerResult.setDays_on_market(Double.valueOf(jsonObject.get("DaysOnMarket").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("BuyerSellerIndex"))) {
                buyerSellerResult.setBuyer_seller_index(Double.valueOf(jsonObject.get("BuyerSellerIndex").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("BuyerSellerIndexMetro"))) {
                buyerSellerResult.setBuyer_seller_index_metro(Double.valueOf(jsonObject.get("BuyerSellerIndexMetro").toString()));
            }
            return new Result<>(ResultCode.SUCCESS, buyerSellerResult);
        }
        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "市场健康指数", notes = "市场健康指数", response = MarketHealthResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path")
    })
    @GetMapping(value = "/marketHealth/{type}/{zip}")
    public Object marketHealth(@PathVariable String type, @PathVariable String zip) {
        type = getType(type);
        String key = "zillow/" + type + "/" + zip + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);
        //重新获取相邻邮编数据
        if (StringUtils.isEmpty(json)) {
            json = getNextToZipJsonByZips(type, zip);
        }
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            MarketHealthResult marketHealthResult = new MarketHealthResult();
            if (!StringUtils.isEmpty(jsonObject.get("MarketHealthIndex"))) {
                marketHealthResult.setMarket_health_index(Double.valueOf(jsonObject.get("MarketHealthIndex").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("SellForGain"))) {
                marketHealthResult.setSell_for_gain(Double.valueOf(jsonObject.get("SellForGain").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("PrevForeclosed"))) {
                marketHealthResult.setPrev_foreclosed(Double.valueOf(jsonObject.get("PrevForeclosed").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("ForeclosureRatio"))) {
                marketHealthResult.setForeclosure_ratio(Double.valueOf(jsonObject.get("ForeclosureRatio").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("ZHVI"))) {
                marketHealthResult.setZhvi(Double.valueOf(jsonObject.get("ZHVI").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("MoM"))) {
                marketHealthResult.setMom(Double.valueOf(jsonObject.get("MoM").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("YoY"))) {
                marketHealthResult.setYoy(Double.valueOf(jsonObject.get("YoY").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("ForecastYoYPctChange"))) {
                marketHealthResult.setForecast_yoy_pct_change(Double.valueOf(jsonObject.get("ForecastYoYPctChange").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("StockOfREOs"))) {
                marketHealthResult.setStock_of_reos(Double.valueOf(jsonObject.get("StockOfREOs").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("NegativeEquity"))) {
                marketHealthResult.setNegative_equity(Double.valueOf(jsonObject.get("NegativeEquity").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("Delinquency"))) {
                marketHealthResult.setDelinquency(Double.valueOf(jsonObject.get("Delinquency").toString()));
            }
            if (!StringUtils.isEmpty(jsonObject.get("DaysOnMarket"))) {
                marketHealthResult.setDays_on_market(Double.valueOf(jsonObject.get("DaysOnMarket").toString()));
            }

            return new Result<>(ResultCode.SUCCESS, marketHealthResult);
        }

        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "租售比", notes = "租售比", response = BreakEvenPRResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path")
    })
    @GetMapping(value = "/sale_rental_ratio/{type}/{zip}")
    public Object saleRentalRatio(@PathVariable String type, @PathVariable String zip) {
        type = getType(type);
        String key = "zillow/" + type + "/zip_" + zip + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);
        //重新获取相邻邮编数据
        if (StringUtils.isEmpty(json)) {
            json = getNextToZipJsonByZips(type, zip);
        }
        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            BreakEvenPRResult breakEvenPRResult = new BreakEvenPRResult();

//            BEPropCount	SampleRate	MedBE	Breakeven	MedPR

            if (!StringUtils.isEmpty(jsonObject.get("BEPropCount"))) {
                breakEvenPRResult.setBe_prop_count(Long.valueOf(jsonObject.getString("BEPropCount")));
            }
            if (!StringUtils.isEmpty(jsonObject.get("SampleRate"))) {
                breakEvenPRResult.setSample_rate(Double.valueOf(jsonObject.getString("SampleRate")));
            }
            if (!StringUtils.isEmpty(jsonObject.get("MedBE"))) {
                breakEvenPRResult.setMed_be(Double.valueOf(jsonObject.getString("MedBE")));
            }
            if (!StringUtils.isEmpty(jsonObject.get("Breakeven"))) {
                breakEvenPRResult.setBrea_keven(jsonObject.getString("Breakeven"));
            }
            if (!StringUtils.isEmpty(jsonObject.get("MedPR"))) {
                breakEvenPRResult.setMed_pr(Double.valueOf(jsonObject.get("MedPR").toString()));
            }

            return new Result<>(ResultCode.SUCCESS, breakEvenPRResult);
        }

        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "租金涨幅百分比预测", notes = "租金涨幅百分比预测", response = ZriForecastPublicResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path")
    })
    @GetMapping(value = "/zri_forecast_public/{type}/{zip}")
    public Object ZriForecastPublic(@PathVariable String type, @PathVariable String zip) {
        type = getType(type);

        Zip entity = zipService.selectByPrimaryKey(zip);
        if (entity == null)
            return new Result(ResultCode.NO_DATA_WAS_FOUND);
        String metro = entity.getMetro();
        if (StringUtils.isEmpty(metro)) {
            System.err.println("================>>metro is null");
            return new Result(ResultCode.METRO_NULL);
        }

        String key = "zillow/" + type + "/" + StringUtil.replaceBlankAndComma(metro) + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);

        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            ZriForecastPublicResult zriForecastPublicResult = new ZriForecastPublicResult();

            if (!StringUtils.isEmpty(jsonObject.get("ZriForecast"))) {
                zriForecastPublicResult.setZri_forecast(Long.valueOf(jsonObject.getString("ZriForecast")));
            }
            if (!StringUtils.isEmpty(jsonObject.get("Forecast_YoY_Change"))) {
                zriForecastPublicResult.setForecast_yoy_change(Double.valueOf(jsonObject.getString("Forecast_YoY_Change")));
            }
            if (!StringUtils.isEmpty(jsonObject.get("Current_YoY_Change"))) {
                zriForecastPublicResult.setCurrent_yoy_change(Double.valueOf(jsonObject.getString("Current_YoY_Change")));
            }
            return new Result<>(ResultCode.SUCCESS, zriForecastPublicResult);
        }

        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "贷款利息", notes = "贷款利息", response = TimeValueItemResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别(97:超大贷款利息,98:传统贷款利息)", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "int", name = "time", value = "年(默认0:表示所有,1：1年,2:2年)", required = false, paramType = "query")
    })
    @GetMapping(value = "/loan_interest/{type}")
    public Object loanInterest(@PathVariable String type, @RequestParam(value = "time", defaultValue = "0") Integer t) {

        String key = "zillow/" + getType(type) + "/" + getType(type) + "_AVG.json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);

        if (!StringUtils.isEmpty(json)) {
            List<TimeValueItemResult> timeValueItemResult = getTimeSeriesDataByYear(json, t);
            return new Result<>(ResultCode.SUCCESS, timeValueItemResult);
        }

        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "存量房统计", notes = "存量房统计", response = InventoryResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "format", value = "格式(count、pct)", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "int", name = "year", value = "年(默认0:表示所有,1：1年,2:2年)", required = false, paramType = "query")

    })
    @GetMapping(value = "/inventory/{format}/{zip}")
    public Object inventory(@PathVariable String format, @PathVariable String zip, @RequestParam(value = "year", defaultValue = "0") Integer year) {
        String type = "99";
        type = getType(type);
        Zip entity = zipService.selectByPrimaryKey(zip);
        if (entity == null)
            return new Result(ResultCode.NO_DATA_WAS_FOUND);
        String metro = entity.getMetro();
        if (StringUtils.isEmpty(metro)) {
            System.err.println("================>>metro is null");
            return new Result<>(ResultCode.SUCCESS);
        }

        String str_variable = null;
        if (format.equals("count")) {
            str_variable = "Inventory Seasonally Adjusted";
        } else if (format.equals("pct")) {
            str_variable = "TierShare";
        } else {
            return new Result<>(ResultCode.SUCCESS);
        }


        String key_top = "zillow/" + type + "/" + StringUtil.replaceBlankAndComma(metro) + "_"
                + StringUtil.replaceBlankAndComma(str_variable) + "_top_tier.json";

        String key_middle = "zillow/" + type + "/" + StringUtil.replaceBlankAndComma(metro) + "_"
                + StringUtil.replaceBlankAndComma(str_variable) + "_middle_tier.json";

        String key_bottom = "zillow/" + type + "/" + StringUtil.replaceBlankAndComma(metro) + "_"
                + StringUtil.replaceBlankAndComma(str_variable) + "_bottom_tier.json";

        System.err.println(key_top);
        System.err.println(key_middle);
        System.err.println(key_bottom);
        String json_top = downloadService.downloadJsonFromOSS(key_top);
        String json_middle = downloadService.downloadJsonFromOSS(key_middle);
        String json_bottom = downloadService.downloadJsonFromOSS(key_bottom);
        InventoryResult inventoryResult = new InventoryResult();

        if (!StringUtils.isEmpty(json_top)) {
            List<TimeValueItemResult> topResult = getSeriesDataByYear(json_top, year);
            inventoryResult.setTop(topResult);
        }
        if (!StringUtils.isEmpty(json_middle)) {
            List<TimeValueItemResult> middleResult = getSeriesDataByYear(json_middle, year);
            inventoryResult.setMiddle(middleResult);
        }
        if (!StringUtils.isEmpty(json_bottom)) {
            List<TimeValueItemResult> bottomResult = getSeriesDataByYear(json_bottom, year);
            inventoryResult.setBottom(bottomResult);
        }
        return new Result<>(ResultCode.SUCCESS, inventoryResult);
    }

    @ApiOperation(value = "负资产率都会区统计", notes = "负资产率都会区统计", response = MetroNETiersResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path")
    })
    @GetMapping(value = "/negative_equity_metro/{type}/{zip}")
    public Object negativeEquityMetro(@PathVariable String type, @PathVariable String zip) {
        type = getType(type);
        Zip entity = zipService.selectByPrimaryKey(zip);
        if (entity == null)
            return new Result(ResultCode.NO_DATA_WAS_FOUND);
        String metro = entity.getMetro();
        if (StringUtils.isEmpty(metro)) {
            System.err.println("================>>metro is null");
            return new Result(ResultCode.METRO_NULL);
        }

        String key = "zillow/" + type + "/" + StringUtil.replaceBlankAndComma(metro) + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);

        if (!StringUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            MetroNETiersResult metroNETiersResult = new MetroNETiersResult();

            if (!StringUtils.isEmpty(jsonObject.get("BottomTierNEPct"))) {
                metroNETiersResult.setBottom_tier_ne_pct(Double.valueOf(jsonObject.getString("BottomTierNEPct")));
            }
            if (!StringUtils.isEmpty(jsonObject.get("MiddleTierNEPct"))) {
                metroNETiersResult.setMiddle_tier_ne_pct(Double.valueOf(jsonObject.getString("MiddleTierNEPct")));
            }
            if (!StringUtils.isEmpty(jsonObject.get("TopTierNEPct"))) {
                metroNETiersResult.setTop_tier_ne_pct(Double.valueOf(jsonObject.getString("TopTierNEPct")));
            }
            return new Result<>(ResultCode.SUCCESS, metroNETiersResult);
        }

        return new Result<>(ResultCode.SUCCESS, null);
    }

    @ApiOperation(value = "负资产率按城市统计", notes = "负资产率按城市统计", response = TimeValueItemResult.class, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "type", value = "类别", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "String", name = "zip", value = "邮编", required = true, paramType = "path"),
            @ApiImplicitParam(dataType = "int", name = "time", value = "年(默认0,0:表示所有,1：1年,2:2年)", required = false, paramType = "query")
    })
    @GetMapping(value = "/negative_equity_city/{type}/{zip}")
    public Object negativeEquityCity(@PathVariable String type, @PathVariable String zip, @RequestParam(value = "time", defaultValue = "0") Integer t) {

        String key = "zillow/" + getType(type) + "/" + zip + ".json";

        if (type.equals("101")) {
            // 101 : 负资产率 按城市 季度更新
            Zip entity = zipService.selectByPrimaryKey(zip);
            if (entity == null)
                return new Result(ResultCode.NO_DATA_WAS_FOUND);
            String city = entity.getCity();
            String state = entity.getState();
            String county = entity.getCounty();
            if (StringUtils.isEmpty(city)) {
                System.err.println("================>>city is null");
                return new Result(ResultCode.CITY_NULL);
            }
            if (StringUtils.isEmpty(county)) {
                System.err.println("================>>county is null");
                return new Result(ResultCode.COUNTY_NULL);
            }

            if (StringUtils.isEmpty(state)) {
                System.err.println("================>>state is null");
                return new Result(ResultCode.STATE_NULL);
            }
            key = "zillow/" + getType(type) + "/city_"
                    + StringUtil.replaceBlankAndComma(city) + "_"  //城市
                    + StringUtil.replaceBlankAndComma(county) + "_" //郡县
                    + StringUtil.replaceBlankAndComma(state)  //州
                    + ".json";
        }

        System.err.println("key:"+key);

        String json = downloadService.downloadJsonFromOSS(key);
        System.err.println(json);
        try {
            if (!StringUtils.isEmpty(json)) {
                JSONObject jsonObject = JSONObject.parseObject(json);
                if (jsonObject.get("time") != null) {
                    String time = jsonObject.get("time").toString();
                    ObjectMapper mapper = new ObjectMapper();
                    List<TimeValueItemResult> timeValueItemResult = mapper.readValue(time, new TypeReference<List<TimeValueItemResult>>() {
                    });
                    //0年 表示获取所有数据
                    if (t != 0 && t > 0) {
                        String dateFormat = "yyyy";
                        Date eTime = new Date();
                        Date bTime = DateUtils.addYear(eTime, -t);
                        //开始截取的时间
                        String startTime = DateUtils.formatDate(bTime, dateFormat);
                        Boolean flag = false; // 开始截取标识
                        List<TimeValueItemResult> items = new ArrayList<>();
                        for (TimeValueItemResult item : timeValueItemResult) {
                            String q = item.getTime().substring(0, item.getTime().indexOf("Q"));
                            System.err.println(item.getTime() + "===" + q + "==" + startTime);
                            if (q.compareTo(startTime)>-1) {
                                flag = true;
                            }
                            if (flag) {
                                System.err.println("item:" + item);
                                items.add(item);
                            }
                        }
                        return new Result<>(ResultCode.SUCCESS, items);
                    }
                    return new Result<>(ResultCode.SUCCESS, timeValueItemResult);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Result<>(ResultCode.SUCCESS, null);
    }

    public String getType(String type) {
        String path = null;
        switch (type) {
            case "1": {
                path = "BuyerSellerIndex_Zip";
                break;
            }
            case "2": {
                path = "InventoryMeasure_SSA_Zip_Public";
                break;
            }
            case "3": {
                path = "InventoryMeasure_Zip_Public";
                break;
            }
            case "4": {
                path = "MarketHealthIndex_Zip";
                break;
            }
            case "5": {
                path = "Zip_Listings_PriceCut_SeasAdj_AllHomes";
                break;
            }
            case "6": {
                path = "Zip_Listings_PriceCut_SeasAdj_Condominum";
                break;
            }
            case "7": {
                path = "Zip_Listings_PriceCut_SeasAdj_SingleFamilyResidence";
                break;
            }
            case "8": {
                path = "Zip_Median_PriceCut_Dollar_AllHomes";
                break;
            }
            case "9": {
                path = "Zip_Median_PriceCut_Dollar_Condominum";
                break;
            }
            case "10": {
                path = "Zip_Median_PriceCut_Dollar_SingleFamilyResidence";
                break;
            }
            case "11": {
                path = "Zip_MedianListingPrice_1Bedroom";
                break;
            }
            case "12": {
                path = "Zip_MedianListingPrice_2Bedroom";
                break;
            }
            case "13": {
                path = "Zip_MedianListingPrice_3Bedroom";
                break;
            }
            case "14": {
                path = "Zip_MedianListingPrice_4Bedroom";
                break;
            }
            case "15": {
                path = "Zip_MedianListingPrice_5BedroomOrMore";
                break;
            }
            case "16": {
                path = "Zip_MedianListingPrice_AllHomes";
                break;
            }
            case "17": {
                path = "Zip_MedianListingPrice_CondoCoop";
                break;
            }
            case "18": {
                path = "Zip_MedianListingPrice_DuplexTriplex";
                break;
            }
            case "19": {
                path = "Zip_MedianListingPrice_Sfr";
                break;
            }
            case "20": {
                path = "Zip_MedianListingPricePerSqft_1Bedroom";
                break;
            }
            case "21": {
                path = "Zip_MedianListingPricePerSqft_2Bedroom";
                break;
            }
            case "22": {
                path = "Zip_MedianListingPricePerSqft_3Bedroom";
                break;
            }
            case "23": {
                path = "Zip_MedianListingPricePerSqft_4Bedroom";
                break;
            }
            case "24": {
                path = "Zip_MedianListingPricePerSqft_5BedroomOrMore";
                break;
            }
            case "25": {
                path = "Zip_MedianListingPricePerSqft_AllHomes";
                break;
            }
            case "26": {
                path = "Zip_MedianListingPricePerSqft_CondoCoop";
                break;
            }
            case "27": {
                path = "Zip_MedianListingPricePerSqft_DuplexTriplex";
                break;
            }
            case "28": {
                path = "Zip_MedianListingPricePerSqft_Sfr";
                break;
            }
            case "29": {
                path = "Zip_MedianPctOfPriceReduction_AllHomes";
                break;
            }
            case "30": {
                path = "Zip_MedianPctOfPriceReduction_Condominum";
                break;
            }
            case "31": {
                path = "Zip_MedianPctOfPriceReduction_SingleFamilyResidence";
                break;
            }
            case "32": {
                path = "Zip_MedianRentalPrice_1Bedroom";
                break;
            }
            case "33": {
                path = "Zip_MedianRentalPrice_2Bedroom";
                break;
            }
            case "34": {
                path = "Zip_MedianRentalPrice_3Bedroom";
                break;
            }
            case "35": {
                path = "Zip_MedianRentalPrice_4Bedroom";
                break;
            }
            case "36": {
                path = "Zip_MedianRentalPrice_5BedroomOrMore";
                break;
            }
            case "37": {
                path = "Zip_MedianRentalPrice_AllHomes";
                break;
            }
            case "38": {
                path = "Zip_MedianRentalPrice_CondoCoop";
                break;
            }
            case "39": {
                path = "Zip_MedianRentalPrice_DuplexTriplex";
                break;
            }
            case "40": {
                path = "Zip_MedianRentalPrice_Mfr5Plus";
                break;
            }
            case "41": {
                path = "Zip_MedianRentalPrice_Sfr";
                break;
            }
            case "42": {
                path = "Zip_MedianRentalPrice_Studio";
                break;
            }
            case "43": {
                path = "Zip_MedianRentalPricePerSqft_1Bedroom";
                break;
            }
            case "44": {
                path = "Zip_MedianRentalPricePerSqft_2Bedroom";
                break;
            }
            case "45": {
                path = "Zip_MedianRentalPricePerSqft_3Bedroom";
                break;
            }
            case "46": {
                path = "Zip_MedianRentalPricePerSqft_4Bedroom";
                break;
            }
            case "47": {
                path = "Zip_MedianRentalPricePerSqft_5BedroomOrMore";
                break;
            }
            case "48": {
                path = "Zip_MedianRentalPricePerSqft_AllHomes";
                break;
            }
            case "49": {
                path = "Zip_MedianRentalPricePerSqft_CondoCoop";
                break;
            }
            case "50": {
                path = "Zip_MedianRentalPricePerSqft_DuplexTriplex";
                break;
            }
            case "51": {
                path = "Zip_MedianRentalPricePerSqft_Mfr5Plus";
                break;
            }
            case "52": {
                path = "Zip_MedianRentalPricePerSqft_Sfr";
                break;
            }
            case "53": {
                path = "Zip_MedianRentalPricePerSqft_Studio";
                break;
            }
            case "54": {
                path = "Zip_MedianValuePerSqft_AllHomes";
                break;
            }
            case "55": {
                path = "Zip_PctOfHomesDecreasingInValues_AllHomes";
                break;
            }
            case "56": {
                path = "Zip_PctOfHomesIncreasingInValues_AllHomes";
                break;
            }
            case "57": {
                path = "Zip_PctOfListingsWithPriceReductions_AllHomes";
                break;
            }
            case "58": {
                path = "Zip_PctOfListingsWithPriceReductions_Condominum";
                break;
            }
            case "59": {
                path = "Zip_PctOfListingsWithPriceReductions_SingleFamilyResidence";
                break;
            }
            case "60": {
                path = "Zip_PriceToRentRatio_AllHomes";
                break;
            }
            case "61": {
                path = "Zip_Zhvi_1bedroom";
                break;
            }
            case "62": {
                path = "Zip_Zhvi_2bedroom";
                break;
            }
            case "63": {
                path = "Zip_Zhvi_3bedroom";
                break;
            }
            case "64": {
                path = "Zip_Zhvi_4bedroom";
                break;
            }
            case "65": {
                path = "Zip_Zhvi_5BedroomOrMore";
                break;
            }
            case "66": {
                path = "Zip_Zhvi_AllHomes";
                break;
            }
            case "67": {
                path = "Zip_Zhvi_BottomTier_yoy";
                break;
            }
            case "68": {
                path = "Zip_Zhvi_BottomTier";
                break;
            }
            case "69": {
                path = "Zip_Zhvi_Condominum";
                break;
            }
            case "70": {
                path = "Zip_Zhvi_MiddleTier_yoy";
                break;
            }
            case "71": {
                path = "Zip_Zhvi_MiddleTier";
                break;
            }
            case "72": {
                path = "Zip_Zhvi_SingleFamilyResidence";
                break;
            }
            case "73": {
                path = "Zip_Zhvi_Summary_AllHomes";
                break;
            }
            case "74": {
                path = "Zip_Zhvi_TopTier_yoy";
                break;
            }
            case "75": {
                path = "Zip_Zhvi_TopTier";
                break;
            }
            case "76": {
                path = "Zip_Zri_AllHomes_Summary";
                break;
            }
            case "77": {
                path = "Zip_Zri_AllHomes";
                break;
            }
            case "78": {
                path = "Zip_Zri_AllHomesPlusMultifamily_Summary";
                break;
            }
            case "79": {
                path = "Zip_Zri_AllHomesPlusMultifamily";
                break;
            }
            case "80": {
                path = "Zip_Zri_MultiFamilyResidenceRental_Summary";
                break;
            }
            case "81": {
                path = "Zip_Zri_MultiFamilyResidenceRental";
                break;
            }
            case "82": {
                path = "Zip_Zri_SingleFamilyResidenceRental_Summary";
                break;
            }
            case "83": {
                path = "Zip_Zri_SingleFamilyResidenceRental";
                break;
            }
            case "84": {
                path = "Zip_ZriPerSqft_AllHomes";
                break;
            }
            //2018-10-23 新增
            case "85": {
                path = "BreakEven_PR"; // 租售比--季度更新
                break;
            }

            case "86": {
                path = "Affordability_Wide_Public"; // 贷款能力 价格收入比 租金能力--季度更新
                break;
            }
            case "87": {
                path = "Affordability_Wide_Public"; // 贷款能力 价格收入比 租金能力--季度更新
                break;
            }
            case "88": {
                path = "Affordability_Wide_Public"; // 贷款能力 价格收入比 租金能力--季度更新
                break;
            }

            case "89": {
                path = "ZriForecast_Public"; // 租金涨幅百分比预测 月更新
                break;
            }
            case "90": {
                path = "SaleToListRatio_City"; // 卖房成功比例  按城市统计	月更新
                break;
            }
            case "91": {
                path = "DaysOnZillow_City"; // 中位挂牌时间 以城市为准 	月更新
                break;
            }
            case "92": {
                path = "Zip_MedianListingPrice_BottomTier"; // 低端房产中位标价	月更新
                break;
            }
            case "93": {
                path = "Zip_MedianListingPrice_TopTier"; // 高端房产中位标价	月更新
                break;
            }
            case "94": {
                path = "Sale_Counts_Zip"; // 房产销售数量 按zip统计	月更新
                break;
            }
            case "95": {
                path = "Sale_Counts_Seas_Adj_City"; // 房产销售数量 按city统计	月更新
                break;
            }
            case "96": {
                path = "Sale_Prices_Zip"; // 所有房产中位售价	月更新
                break;
            }
            case "97": {
                path = "MortgageRateJumboFixed"; // 超大贷款利息	星期更新
                break;
            }
            case "98": {
                path = "MortgageRateConventionalFixed"; // 传统贷款利息	星期更新
                break;
            }
            case "99": {
                path = "InventoryMeasure_Tiers_Metro_Public"; // 存量房数字 大都市圈  月更新
                break;
            }
            case "100": {
                path = "Metro_NETiers"; // 大都会区负资产率按房产级别排序  季度更新
                break;
            }
            case "101": {
                path = "NegativeEquity"; // 负资产率 按城市 季度更新
                break;
            }
            case "102": {
                path = "MonthlyTurnover_Zip"; // 房产换手率	月更新
                break;
            }
            case "103": {
                path = "ForeclosuresPer10Khomes_Zip"; // 法拍房比例  10000个房产里面的法拍个数	月更新
                break;
            }
            case "104": {
                path = "Affordability_Income"; // 中位家庭收入   都会区  季度更新
                break;
            }
            default: {
                break;
            }
        }

        return path;
    }


    /***
     * 重新获取相邻邮编数据
     * @param type 文件路径
     * @param zip 邮编
     * @return json 字符串
     */
    public String getNextToZipJsonByZips(String type, String zip) {
        if(isSearchAdjacentZip) {
            String json = null;
            String key;
            List<String> zipCodes = zipService.selectSameCityZipsByZip(zip);
            System.err.println("==============>>zipCodes:" + zipCodes.toString());
            if (zipCodes != null && zipCodes.size() > 0) {
                final int len = zipCodes.size();
                for (int i = 0; i < len; i++) {
                    String postcode = StringUtil.getZip(zipCodes, zip);
                    System.err.println("====相邻zip:" + postcode);
                    zipCodes.remove(postcode); //数组中删除与zip 最近的邮编
                    key = "zillow/" + type + "/" + postcode + ".json";
                    json = downloadService.downloadJsonFromOSS(key); //重新获取json 数据
                    if (!StringUtils.isEmpty(json)) {
                        break;
                    }
                }
            }
            return json;
        }

        return null;
    }
}
